package com.xiaoshuidi.cloud.module.iot.controller.admin.aspects;

import com.alibaba.fastjson.JSONObject;
import com.xiaoshuidi.cloud.module.iot.annotation.PreventRepetitionAnnotation;
import com.xiaoshuidi.cloud.module.iot.common.ResultModel;
import com.xiaoshuidi.cloud.module.iot.enums.ErrorCodeEnum;
import com.xiaoshuidi.cloud.module.iot.service.InteceptorService;
import com.xiaoshuidi.cloud.module.iot.uitils.IPUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;


/**
 * @author Sky
 * create 2019/03/05
 * email sky.li@ixiaoshuidi.com
 **/
@Aspect
@Component
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class PreventRepetitionAspect {

    private final static Logger LOGGER = LoggerFactory.getLogger(PreventRepetitionAspect.class);


    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private InteceptorService inteceptorService;

    @Around("@annotation(com.xiaoshuidi.cloud.module.iot.annotation.PreventRepetitionAnnotation)")
    public Object excute(ProceedingJoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method targetMethod = methodSignature.getMethod();
        PreventRepetitionAnnotation annotation = targetMethod.getAnnotation(PreventRepetitionAnnotation.class);
        //组装key
        String cacheKey = IPUtil.getIpAddr(request) + "_" + targetMethod.getName();
        LOGGER.info("PreventRepetitionAspect,生成的key:{}", cacheKey);
        long requestCount = redisTemplate.opsForValue().increment(cacheKey, 1);
        if (requestCount == 1) {
            //设置缓存时间1S，不能重复提交
            redisTemplate.expire(cacheKey, annotation.timeout(), TimeUnit.SECONDS);
        } else {
            LOGGER.info("请勿重复提交，请求路径：{}，请求方法：{}", request.getRequestURL(), targetMethod.getName());
            return ResultModel.createNativeFail(annotation.message());
        }
        Object result = joinPoint.proceed();
        return result;
    }

    @Around("@annotation(com.xiaoshuidi.cloud.module.iot.annotation.OperationDataAccessAnnotation)")
    public Object OperationDataAccess(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] objects = joinPoint.getArgs();
        LOGGER.info("设备相关操作"+objects.length);
        String body = JSONObject.toJSONString(objects[0]);
        JSONObject json = JSONObject.parseObject(body);
        System.out.println(json);
        String deviceNo = json.getString("deviceNo");
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String url = request.getRequestURI();
        Integer opType = null;
        switch (url) {
            case "/admin-api/iot/doorlock/password/addPassword":
                //添加密码
                opType = 2;
                break;
            case "/admin-api/iot/doorlock/password/updatePassword":
                //修改密码
                opType = 4;
                break;
            case "/admin-api/iot/doorlock/password/frozenPassword":
                //冻结密码
                opType = 5;
                break;
            case "/admin-api/iot/doorlock/password/unfrozenPassword":
                //解冻密码
                opType = 6;
                break;
            case "/admin-api/iot/doorlock/password/deletePassword":
                //删除密码
                opType = 3;
                break;
            case "/admin-api/iot/ammeter/manage/setAmmeterSwitchOn":
                //合闸操作
                opType = 9;
                inteceptorService.addOperateRecord( deviceNo, opType);
                return joinPoint.proceed();
            case "/admin-api/iot/ammeter/manage/setAmmeterSwitchOff":
                //跳闸操作
                opType = 10;
                inteceptorService.addOperateRecord( deviceNo, opType);
                return joinPoint.proceed();
            case "/admin-api/iot/watermeter/manage/setWaterMeterSwitchOn" :
                //水表合闸
                opType = 9;
                inteceptorService.addOperateRecord( deviceNo, opType);
                return joinPoint.proceed();
            case "/admin-api/iot/watermeter/manage/setWaterMeterSwitchOff":
                //水表跳闸
                opType = 10;
                inteceptorService.addOperateRecord( deviceNo, opType);
                return joinPoint.proceed();
            default:
                //不符合拦截
                return true;
        }
        Integer id = inteceptorService.addOperateRecord( deviceNo, opType);
        Object object = joinPoint.proceed();
        String result = JSONObject.toJSONString(object);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (ErrorCodeEnum.CODE_INIT.getCode().equals(jsonObject.getString("code"))) {
            JSONObject jsonObject1 = jsonObject.getJSONObject("data");
            jsonObject1.put("operateRecordId", id);
            //成功后处理数据
            inteceptorService.updateOperateRecord(jsonObject1);
        }
        return object;
    }
}
